﻿using System;
using System.Collections.Generic;
using Game.modules;
using Game.modules.properties;
using GameFramework.common;
using GameFramework.data;
using GameFramework.scripts;
using UnityEngine;

namespace GameFramework.properties
{
    public class PropertyManager:Singleton<PropertyManager>
    {
        //各个功能对应的基础属性{功能id：{属性id，属性值}}
        private Dictionary<int, Dictionary<int,float>> funcProperties = new Dictionary<int, Dictionary<int,float>>();
        //各个功能对应的属性加成万分比{功能id：{属性id，属性加成万分比}}
        private Dictionary<int, Dictionary<int,int>> funcPropertyPercent= new Dictionary<int,Dictionary<int,int>>();
        //各个功能基础属性之和
        public float[] baseValues;
        //各个功能所有属性百分比之和
        public float[] percents;
        
        /// <summary>
        /// 计算指定功能的属性，只有在基础属性或对应的加成百分比变化时才重新计算属性
        /// </summary>
        /// <param name="playerData"></param>
        /// <param name="funcId"></param>
        public void caculatePlayerFuncProperty(PlayerData playerData,int funcId)
        {
            //调用具体的功能属性脚本进行计算
            IPropertyCalScript calScript = PropertyCalScriptManager.Instance.getScript(funcId);
            if (calScript == null)
            {
                Debug.LogError("未找到功能对应的属性计算脚本，功能id："+funcId);
                return;
            }

            if (!funcProperties.ContainsKey(funcId))
            {
                funcProperties.Add(funcId,new Dictionary<int, float>());
            }

            bool changed = false;
            try
            {
                changed |=calScript.caculate(funcProperties[funcId],playerData);
                changed |=calScript.caculatePercent(funcPropertyPercent[funcId],playerData);
            }
            catch (Exception e)//计算出错，则暂时把这个功能的所有属性给去掉，以免影响其他功能
            {
                funcProperties.Remove(funcId);
                funcPropertyPercent.Remove(funcId);
                Debug.LogError(e);
                return;
            }

            if (!changed)//没有属性变化
            {
                return;
            }

            //所有功能属性重新汇总
            Dictionary<int, float> finallyProperties = new Dictionary<int, float>();
            foreach (Dictionary<int,float> funcPropertiesValue in funcProperties.Values)
            {
                foreach (KeyValuePair<int,float> keyValuePair in funcPropertiesValue)
                {
                    int key = keyValuePair.Key;
                    float value = keyValuePair.Value;
                    if (finallyProperties.ContainsKey(key))
                    {
                        finallyProperties[key] += value;
                    }

                    finallyProperties[key] = value;
                }
            }
            Dictionary<int, float> finallyPropertyPercent = new Dictionary<int, float>();
            foreach (Dictionary<int,int> dictionary in funcPropertyPercent.Values)
            {
                foreach (KeyValuePair<int,int> keyValuePair in dictionary)
                {
                    int key = keyValuePair.Key;
                    float value = keyValuePair.Value;
                    if (finallyPropertyPercent.ContainsKey(key))
                    {
                        finallyPropertyPercent[key] += value;
                    }

                    finallyPropertyPercent[key] = value;
                }
            }
            
            foreach (KeyValuePair<int,float> keyValuePair in finallyProperties)
            {
                int key = keyValuePair.Key;
                float value = keyValuePair.Value;
                if (finallyPropertyPercent.ContainsKey(key))
                {
                    finallyProperties[key] = finallyProperties[key] * (1 + value/10000);
                }
            }
            //有属性变化则发布属性变化事件
            // EventManager.Instance.dispatch();
        }
        /// <summary>
        /// 计算指定的功能属性
        /// </summary>
        /// <param name="playerData"></param>
        /// <param name="funcIds"></param>
        public void caculatePlayerFuncProperty(PlayerData playerData,List<int> funcIds)
        {
            //调用具体的功能属性脚本进行计算
            
            //所有功能属性重新汇总
            //有属性变化则发布属性变化事件
        }
        /// <summary>
        /// 计算所有功能的属性
        /// </summary>
        /// <param name="playerData"></param>
        public void caculatePlayerAllProperty(PlayerData playerData)
        {
            //调用所有的功能属性脚本进行计算
            
            //所有功能属性重新汇总
            //有属性变化则发布属性变化事件
        }
        
        /// <summary>
        /// TODO monster属性计算，需要传入monster对象，主要是给monster加Buff后从新计算属性
        /// </summary>
        /// <param name="playerData"></param>
        public void caculateMonsterProperty(PlayerData playerData)
        {
            //调用所有的功能属性脚本进行计算
            
            //所有功能属性重新汇总
            //有属性变化则发布属性变化事件
        }
    }
}